﻿/**************************
 * Author: Hientt
 * Date: 17/03/2013
 * Module: 
 * Project: OFB
 **************************/

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Data.SqlClient;
using System.Data;
using System.Reflection;

namespace Advertising.DataAccess.Common
{
    /// <summary>
    /// This class perform all query with SqlServer
    /// </summary>
    /// <typeparam name="TViewData"></typeparam>
    public class DataQuery<TViewData> : DataObject
    {
        /// <summary>
        /// object hold mapped data
        /// </summary>
        private dynamic MappingObject;
        /// <summary> 
        /// Contructor for DataQuery class with a input connectionString
        /// </summary>
        /// <param name="connectionStringName"></param>
        public DataQuery(string connectionStringName) : base(ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString)
        {
            MappingObject=Activator.CreateInstance<TViewData>();
        }
         
        /// <summary>
        /// Init/Set up the SqlConnection
        /// </summary>
        /// <param name="storeName"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public DataQuery<TViewData> Init(string storeName, params IDataParameter[] paras)
        {
            SqlDataReader reader=ExecuteQuery(storeName, paras);
            Mapping.Reader=reader;

            return this;
        }

        /// <summary>
        /// Map data for a current object's properties
        /// </summary>
        /// <returns></returns>
        public DataQuery<TViewData> Map()
        {
            MappingObject=Mapping.MapSingleObject<TViewData>();
            return this;
        }

        /// <summary>
        /// Map data for a collection's properties
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public DataQuery<TViewData> MapCollection<T>()
        {
            MappingObject=Mapping.MapCollectionObject<T>();
            return this;
        }

        /// <summary>
        /// Map data for a object's properties include in current object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <param name="isNextResult"></param>
        /// <returns></returns>
        public DataQuery<TViewData> Include<T>(string propertyName, bool isNextResult = false)
        {
            Type type=typeof(TViewData);
            PropertyInfo property=type.GetProperty(propertyName);
            if (property == null)
                throw new ArgumentException("Thuoc tinh khong ton tai");

            property.SetValue(MappingObject, Mapping.MapSingleObject<T>(isNextResult), null);

            return this;
        }

        /// <summary>
        /// Map data for a collection include in current object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <param name="isNextResult"></param>
        /// <returns></returns>
        public DataQuery<TViewData> IncludeCollection<T>(string propertyName, bool isNextResult = false)
        {
            Type type=typeof(TViewData);
            PropertyInfo property=type.GetProperty(propertyName);
            if (property == null)
                throw new ArgumentException("Thuoc tinh khong ton tai");

            property.SetValue(MappingObject, Mapping.MapCollectionObject<T>(isNextResult), null);

            return this;
        }

        /// <summary>
        /// Get a single object
        /// </summary>
        /// <returns></returns>
        public TViewData Get()
        {
            Mapping.Reader.Close();
            Mapping.Reader.Dispose();

            return MappingObject;
        }

        /// <summary>
        /// Get a collection of object
        /// </summary>
        /// <returns></returns>
        public ICollection<TViewData> GetCollection()
        {
            Mapping.Reader.Close();
            Mapping.Reader.Dispose();

            return MappingObject;
        }
    }
}
